/**
 * 实现ajax封装有两个方法 ajax为智能接口，myAjax为手动设置版，ajax接口会自动处理数据 contentType 自动判断设置是否跨域带数据
 * @param 取值为0-3分别为"GET", "POST", "PUT", "DELETE"
 * @param 请求地址
 * @param 成功回调
 * @param 请求数据
 * @param 错误回调
 * @param beforSend设置支持对像（多个key）或字符串如果是字符串会默认 setRequestHeader('Authorization', token);如果是对像的话key即为setRequestHeader的第一个参数
 * @param contentType（该参数如非特别需要可自动处理）
 * @return void
 * @author lizuping 2018/05/08
 * @example ajax(met, url, suc, data, err, token, cy)
 * myAjax示例
 * @example myAjax({
            url: '',
            type: 'GET', // 请求方式
            data: false, // 请求数据
            dataType: 'JSON', // 预期返回数据类型
            cache: false,
            contentType: false,
            timeout: 0, // 超时
            withCredentials: false, // 跨域带数据
            success: function () {},
            error: function (e) {
                console.log(e);
            },
            token: false
        })
 */
function AllFunc () {}
AllFunc.prototype = {
    // 七个参数分别的请求地址，请求数据，成功回调，错误回调，beforSend设置及contentType（该参数如非特别需要可自动处理）
    // 自定义ajax,met可取值为0-3分别为"GET", "POST", "PUT", "DELETE"
    ajax: function (met, url, suc, data, err, token, cy) {
        var that = this;
        met = parseInt(met, 10);
        met = isNaN(met) ? 0 : met > 3 ? 3 : met < 0 ? 0 : met;
        data = data || null;
        var m = ['GET', 'POST', 'PUT', 'DELETE'];
        cy = cy || 'application/x-www-form-urlencoded; charset=UTF-8';
        if (met > 0) {
            if (data && (typeof (data) === 'object' && typeof (data.append) === 'function')) {
                cy = false;
            }
            if (data && (typeof (data) === 'string')) {
                cy = 'application/json; charset=UTF-8';
            }
        } else { cy = false; }
        var f = function () {};
        err = err || f;
        suc = suc || f;
        that.myAjax({
            type: m[met],
            url: url,
            contentType: cy,
            data: data,
            cache: false,
            token: token || false,
            error: function (d) {
                err(d);
            },
            success: function (d) {
                suc(d);
            }
        });
    },
    myAjax: function (o) {
        o = ext({
            url: '',
            type: 'GET', // 请求方式
            data: false, // 请求数据
            dataType: 'JSON', // 数据类型
            cache: false,
            contentType: false,
            timeout: 0, // 超时
            withCredentials: false, // 跨域带数据
            token: false
        },
        o || {});

        function ext (a, b) {
            for (var k in b) {
                if (b.hasOwnProperty(k)) {
                    a[k] = b[k];
                }
            }
            return a;
        }

        function obj (b) {
            var temp = '';
            for (var i in b) {
                if (b.hasOwnProperty(i)) {
                    temp += i + '=' + encodeURIComponent(b[i]) + '&';
                }
            }
            return temp.slice(0, -1);
        }

        function AjaxMy (o) {
            // 回调函数
            function onreadystatechange (func, _xhr) {
                _xhr.onreadystatechange = function () {
                    if (_xhr.readyState === 4) {
                        try {
                            if (_xhr.status >= 200 && _xhr.status < 300) {
                                var rT = _xhr.responseText;
                                if (o.dataType.toUpperCase() === 'JSON') {
                                    try {
                                        rT = JSON.parse(rT);
                                    } catch (e) {
                                        console.log(e);
                                    }
                                }
                                func(rT);
                            } else {
                                setTimeout(function () {
                                    if (funcKs) {
                                        o.error.call(this, _xhr.status);
                                    }
                                },
                                50);
                            }
                        } catch (e) {
                            setTimeout(function () {
                                if (funcKs) {
                                    o.error.call(this, e);
                                }
                            },
                            50);
                        }
                        xhr = null;
                    }
                };
            }
            // 判断是否同域
            function dma (url) {
                if (/^\//.exec(url)) {
                    return true;
                }
                if (url.search(window.location.host) > -1) {
                    var s = window.location.port ? window.location.port : '8080';
                    var s2 = /https?:\/\/[^:]+:(\d+)/.exec(url);
                    s2 = s2 ? s2[1] : '8080';
                    return s === s2;
                } else {
                    return false;
                }
            }

            var xhr = new XMLHttpRequest();
            var funcKs = true;
            o.data = o.data ? o.data : false;
            o.type = o.type.toUpperCase();
            var rts = /([?&])_=[^&]*/,
                ajaxRquery = /\?/;
            if (o.type === 'GET') {
                if (o.data) {
                    if (typeof (o.data) === 'object') {
                        o.data = obj(o.data, true);
                    }
                    o.url = rts.test(o.url) ? o.url.replace(rts, '$1' + o.data) : o.url + (ajaxRquery.test(o.url) ? '&' : '?') + o.data;
                }
                o.data = null;
                if (!o.cache) {
                    var thisT = new Date().getTime();
                    o.url = rts.test(o.url) ? o.url.replace(rts, '$1_=' + thisT) : o.url + (ajaxRquery.test(o.url) ? '&' : '?') + '_=' + thisT;
                }
            }
            // 跨域带数据
            var isDma = dma(o.url);
            if (o.withCredentials && !isDma) {
                xhr.withCredentials = true;
            }
            // 设置token
            function setToken (request, token) {
                if (typeof (token) === 'string') { request.setRequestHeader('Authorization', token); }
                if (typeof (token) === 'object') {
                    for (var key in token) {
                        request.setRequestHeader(key, token[key]);
                    }
                }
            };

            xhr.open(o.type, o.url, true);
            if (xhr.overrideMimeType) {
                xhr.overrideMimeType('mimeType');
            }
            if (o.token) {
                setToken(xhr, o.token);
            }
            if (isDma) {
                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            }
            var settime = parseInt(o.timeout, 10);
            // 超时判断
            if (settime && settime > 0) {
                xhr.timeout = settime;
                if (xhr.timeout !== 'undefined') {
                    xhr.timeout = o.timeout;
                    funcKs = false;
                    xhr.ontimeout = function () {
                        o.error.call(this, 'timeout');
                    };
                } else {
                    console.log('不支持超时设置');
                }
            }

            if (o.contentType) {
                // setRequestHeader 一个都不设置跨域时就不会出现options请求
                // X-requested-with 显示的告诉服务端是异步
                if (!isDma) {
                    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
                }

                xhr.setRequestHeader('Content-Type', o.contentType);

                if (o.data) {
                    o.data = typeof (o.data) === 'string' ? o.data : obj(o.data);
                }
            }

            onreadystatechange(o.success, xhr);
            if (o.data) {
                xhr.send(o.data);
            } else {
                xhr.send();
            }
        }

        new AjaxMy(o);
    }

};

export default new AllFunc();
